﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Net;
using System.Xml;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
using System.ServiceModel.Syndication;

namespace rambla.raws.rats
{
    public class ratsConnection
    {
        private const string cContentType = "application/atom+xml;type=entry";
        private const string cBaseURL = "http://rats.enc01.rambla.be";

        internal NetworkCredential Credentials;

        public ratsConnection(string usrName, string pwd)
        {
            Credentials = new NetworkCredential(usrName, pwd);
        }

        public User userInfo
        {
            get
            {
                return getObject<User>("/user/" + Credentials.UserName);
            }
        }

        public inputProfiles inputProfiles
        {
            get
            {
                return new inputProfiles(this);
            }
        }

        public outputProfiles outputProfiles
        {
            get
            {
                return new outputProfiles(this);
            }
        }

        public formatProfiles formatProfiles
        {
            get
            {
                return new formatProfiles(this);
            }
        }

        public Jobs jobs
        {
            get
            {
                return new Jobs(this);
            }
        }

        public scrFiles scrFiles 
        {
            get
            {
                return new scrFiles(this);
            }
        }

        public transcFiles transcFiles 
        {
            get
            {
                return new transcFiles(this);
            }
        }

        internal T getObject<T>(string command)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(cBaseURL + command);
            req.Headers.Add("Authorization","Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(Credentials.UserName + ":" + Credentials.Password)));
            req.Method = "GET";
            WebResponse resp = req.GetResponse();
            Atom10ItemFormatter formatter = new Atom10ItemFormatter();
            formatter.ReadFrom(XmlReader.Create(resp.GetResponseStream()));
            SyndicationItem item = formatter.Item;
            string val = ((XmlReader)((XmlSyndicationContent)item.Content).GetReaderAtContent()).ReadInnerXml();
            return XMLSerializationUtility.DeserializeObject<T>(Encoding.UTF8, val);
        }

        internal T[] getObjects<T>(string command)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(cBaseURL + command);
            req.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(Credentials.UserName + ":" + Credentials.Password)));
            req.Method = "GET";
            WebResponse resp = req.GetResponse();
            Atom10FeedFormatter formatter = new Atom10FeedFormatter();
            formatter.ReadFrom(XmlReader.Create(resp.GetResponseStream()));

            T[] _out = new T[formatter.Feed.Items.Count()];
            int counter = 0;
            foreach (SyndicationItem item in formatter.Feed.Items)
            {
                string val = ((XmlReader)((XmlSyndicationContent)item.Content).GetReaderAtContent()).ReadInnerXml();
                _out[counter] = XMLSerializationUtility.DeserializeObject<T>(Encoding.UTF8, val);
                counter++;
            }

            return _out;
        }

        internal void postObject<T>(string command, T obj)
        {

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(cBaseURL + command);
            req.ContentType = cContentType;
            req.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(Credentials.UserName + ":" + Credentials.Password)));
            req.Method = "POST";
            

            SyndicationItem Item = new SyndicationItem();
            Item.Content = new XmlSyndicationContent("application/xml",obj,new XmlSerializer(typeof(T)));

            XmlWriter outStream = XmlWriter.Create(req.GetRequestStream());
            Item.GetAtom10Formatter().WriteTo(outStream);
            outStream.Flush();
            outStream.Close();

            req.GetRequestStream().Flush();
            req.GetRequestStream().Close();

            WebResponse resp = req.GetResponse();
        }

        internal void uploadFile(string command, string filename, string targetFilename)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(cBaseURL + command);
            req.AllowAutoRedirect = false;
            req.ContentType = "binary data";
            req.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(Credentials.UserName + ":" + Credentials.Password)));
            req.PreAuthenticate = true;
            req.Method = "POST";
            req.Headers.Add("Slug", targetFilename);

            byte[] file = File.ReadAllBytes(filename);
            req.GetRequestStream().Write(file, 0, file.Length);
            req.GetRequestStream().Flush();
            req.GetRequestStream().Close();


            WebResponse resp = req.GetResponse();
        }

        internal byte[] downloadFile(string command)
        {
            WebClient req = new WebClient();
            req.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(Credentials.UserName + ":" + Credentials.Password)));
            return req.DownloadData(cBaseURL + command);
        }

        internal void deleteObject(string command)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(cBaseURL + command);
            req.ContentType = cContentType;
            req.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(Credentials.UserName + ":" + Credentials.Password)));
            req.PreAuthenticate = true;
            req.Method = "DELETE";

            WebResponse resp = req.GetResponse();
        }
    }
}
